/*
 * tb_hwpe_ctrl_uloop.sv
 * Francesco Conti <fconti@iis.ee.ethz.ch>
 *
 * Copyright (C) 2019 ETH Zurich, University of Bologna
 * Copyright and related rights are licensed under the Solderpad Hardware
 * License, Version 0.51 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
 * or agreed to in writing, software, hardware and materials distributed under
 * this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 */

timeunit 1ps;
timeprecision 1ps;


module tb_hwpe_ctrl_uloop;
  import hwpe_ctrl_package::*;

  // parameters
  parameter int unsigned NB_LOOPS  = hwpe_ctrl_package::ULOOP_NB_LOOPS;
  parameter int unsigned LENGTH    = hwpe_ctrl_package::ULOOP_LENGTH;
  parameter int unsigned NB_RO_REG = 12;
  parameter int unsigned NB_REG    = 4;
  parameter int unsigned REG_WIDTH = hwpe_ctrl_package::ULOOP_REG_WIDTH;
  parameter int unsigned CNT_WIDTH = hwpe_ctrl_package::ULOOP_CNT_WIDTH;
  parameter int unsigned SHADOWED  = 1; // hwpe_ctrl_package::ULOOP_SHADOWED;

  // testbench parameters -- see uloop-example/uloop_run.py
  int oh         = 3;
  int ow         = 3;
  int nof_div_TP = 384/128;
  int fs1        = 3;
  int fs0        = 3;
  int nif_div_TP = 384/128;

  // signals
  logic                                clk_i = '0;
  logic                                rst_ni = '1;
  logic                                test_mode_i = '0;
  logic                                clear_i = '0;
  ctrl_uloop_t                         ctrl_i;
  flags_uloop_t                        flags_o;
  uloop_code_t                         uloop_code_i;
  logic [NB_RO_REG-1:0][REG_WIDTH-1:0] registers_read_i;

  // ATI timing parameters.
  localparam TCP = 1.0ns; // clock period, 1 GHz clock
  localparam TA  = 0.2ns; // application time
  localparam TT  = 0.8ns; // test time

  // Performs one entire clock cycle.
  task cycle;
    clk_i <= #(TCP/2) 0;
    clk_i <= #TCP 1;
    #TCP;
  endtask

  // The following task schedules the clock edges for the next cycle and
  // advances the simulation time to that cycles test time (localparam TT)
  // according to ATI timings.
  task cycle_start;
    clk_i <= #(TCP/2) 0;
    clk_i <= #TCP 1;
    #TT;
  endtask

  // The following task finishes a clock cycle previously started with
  // cycle_start by advancing the simulation time to the end of the cycle.
  task cycle_end;
    #(TCP-TT);
  endtask

  hwpe_ctrl_uloop #(
    .NB_LOOPS  ( NB_LOOPS  ),
    .LENGTH    ( LENGTH    ),
    .NB_RO_REG ( NB_RO_REG ),
    .NB_REG    ( NB_REG    ),
    .REG_WIDTH ( REG_WIDTH ),
    .CNT_WIDTH ( CNT_WIDTH ),
    .SHADOWED  ( SHADOWED  )
  ) i_uloop (
    .clk_i            ( clk_i            ),
    .rst_ni           ( rst_ni           ),
    .test_mode_i      ( test_mode_i      ),
    .clear_i          ( clear_i          ),
    .ctrl_i           ( ctrl_i           ),
    .flags_o          ( flags_o          ),
    .uloop_code_i     ( uloop_code_i     ),
    .registers_read_i ( registers_read_i )
  );

  // clock/reset gen process
  initial begin
    #(20*TCP);

    // Reset phase.
    rst_ni <= #TA 1'b0;
    #(20*TCP);
    rst_ni <= #TA 1'b1;

    for (int i = 0; i < 10; i++)
      cycle();
    rst_ni <= #TA 1'b0;
    for (int i = 0; i < 10; i++)
      cycle();
    rst_ni <= #TA 1'b1;

    while(1) begin
      cycle();
    end

  end

  // see uloop-example/uloop_run.py
  logic [0:729][0:3][31:0] ground_truth = {
    {0,0,0,0},
    {128,128,0,0},
    {256,256,0,0},
    {384,384,0,0},
    {512,512,0,0},
    {640,640,0,0},
    {768,768,0,0},
    {896,896,0,0},
    {1024,1024,0,0},
    {1152,1920,0,0},
    {1280,2048,0,0},
    {1408,2176,0,0},
    {1536,2304,0,0},
    {1664,2432,0,0},
    {1792,2560,0,0},
    {1920,2688,0,0},
    {2048,2816,0,0},
    {2176,2944,0,0},
    {2304,3840,0,0},
    {2432,3968,0,0},
    {2560,4096,0,0},
    {2688,4224,0,0},
    {2816,4352,0,0},
    {2944,4480,0,0},
    {3072,4608,0,0},
    {3200,4736,0,0},
    {3328,4864,0,0},
    {3456,0,128,0},
    {3584,128,128,0},
    {3712,256,128,0},
    {3840,384,128,0},
    {3968,512,128,0},
    {4096,640,128,0},
    {4224,768,128,0},
    {4352,896,128,0},
    {4480,1024,128,0},
    {4608,1920,128,0},
    {4736,2048,128,0},
    {4864,2176,128,0},
    {4992,2304,128,0},
    {5120,2432,128,0},
    {5248,2560,128,0},
    {5376,2688,128,0},
    {5504,2816,128,0},
    {5632,2944,128,0},
    {5760,3840,128,0},
    {5888,3968,128,0},
    {6016,4096,128,0},
    {6144,4224,128,0},
    {6272,4352,128,0},
    {6400,4480,128,0},
    {6528,4608,128,0},
    {6656,4736,128,0},
    {6784,4864,128,0},
    {6912,0,256,0},
    {7040,128,256,0},
    {7168,256,256,0},
    {7296,384,256,0},
    {7424,512,256,0},
    {7552,640,256,0},
    {7680,768,256,0},
    {7808,896,256,0},
    {7936,1024,256,0},
    {8064,1920,256,0},
    {8192,2048,256,0},
    {8320,2176,256,0},
    {8448,2304,256,0},
    {8576,2432,256,0},
    {8704,2560,256,0},
    {8832,2688,256,0},
    {8960,2816,256,0},
    {9088,2944,256,0},
    {9216,3840,256,0},
    {9344,3968,256,0},
    {9472,4096,256,0},
    {9600,4224,256,0},
    {9728,4352,256,0},
    {9856,4480,256,0},
    {9984,4608,256,0},
    {10112,4736,256,0},
    {10240,4864,256,0},
    {0,384,384,384},
    {128,512,384,384},
    {256,640,384,384},
    {384,768,384,384},
    {512,896,384,384},
    {640,1024,384,384},
    {768,1152,384,384},
    {896,1280,384,384},
    {1024,1408,384,384},
    {1152,2304,384,384},
    {1280,2432,384,384},
    {1408,2560,384,384},
    {1536,2688,384,384},
    {1664,2816,384,384},
    {1792,2944,384,384},
    {1920,3072,384,384},
    {2048,3200,384,384},
    {2176,3328,384,384},
    {2304,4224,384,384},
    {2432,4352,384,384},
    {2560,4480,384,384},
    {2688,4608,384,384},
    {2816,4736,384,384},
    {2944,4864,384,384},
    {3072,4992,384,384},
    {3200,5120,384,384},
    {3328,5248,384,384},
    {3456,384,512,384},
    {3584,512,512,384},
    {3712,640,512,384},
    {3840,768,512,384},
    {3968,896,512,384},
    {4096,1024,512,384},
    {4224,1152,512,384},
    {4352,1280,512,384},
    {4480,1408,512,384},
    {4608,2304,512,384},
    {4736,2432,512,384},
    {4864,2560,512,384},
    {4992,2688,512,384},
    {5120,2816,512,384},
    {5248,2944,512,384},
    {5376,3072,512,384},
    {5504,3200,512,384},
    {5632,3328,512,384},
    {5760,4224,512,384},
    {5888,4352,512,384},
    {6016,4480,512,384},
    {6144,4608,512,384},
    {6272,4736,512,384},
    {6400,4864,512,384},
    {6528,4992,512,384},
    {6656,5120,512,384},
    {6784,5248,512,384},
    {6912,384,640,384},
    {7040,512,640,384},
    {7168,640,640,384},
    {7296,768,640,384},
    {7424,896,640,384},
    {7552,1024,640,384},
    {7680,1152,640,384},
    {7808,1280,640,384},
    {7936,1408,640,384},
    {8064,2304,640,384},
    {8192,2432,640,384},
    {8320,2560,640,384},
    {8448,2688,640,384},
    {8576,2816,640,384},
    {8704,2944,640,384},
    {8832,3072,640,384},
    {8960,3200,640,384},
    {9088,3328,640,384},
    {9216,4224,640,384},
    {9344,4352,640,384},
    {9472,4480,640,384},
    {9600,4608,640,384},
    {9728,4736,640,384},
    {9856,4864,640,384},
    {9984,4992,640,384},
    {10112,5120,640,384},
    {10240,5248,640,384},
    {0,768,768,768},
    {128,896,768,768},
    {256,1024,768,768},
    {384,1152,768,768},
    {512,1280,768,768},
    {640,1408,768,768},
    {768,1536,768,768},
    {896,1664,768,768},
    {1024,1792,768,768},
    {1152,2688,768,768},
    {1280,2816,768,768},
    {1408,2944,768,768},
    {1536,3072,768,768},
    {1664,3200,768,768},
    {1792,3328,768,768},
    {1920,3456,768,768},
    {2048,3584,768,768},
    {2176,3712,768,768},
    {2304,4608,768,768},
    {2432,4736,768,768},
    {2560,4864,768,768},
    {2688,4992,768,768},
    {2816,5120,768,768},
    {2944,5248,768,768},
    {3072,5376,768,768},
    {3200,5504,768,768},
    {3328,5632,768,768},
    {3456,768,896,768},
    {3584,896,896,768},
    {3712,1024,896,768},
    {3840,1152,896,768},
    {3968,1280,896,768},
    {4096,1408,896,768},
    {4224,1536,896,768},
    {4352,1664,896,768},
    {4480,1792,896,768},
    {4608,2688,896,768},
    {4736,2816,896,768},
    {4864,2944,896,768},
    {4992,3072,896,768},
    {5120,3200,896,768},
    {5248,3328,896,768},
    {5376,3456,896,768},
    {5504,3584,896,768},
    {5632,3712,896,768},
    {5760,4608,896,768},
    {5888,4736,896,768},
    {6016,4864,896,768},
    {6144,4992,896,768},
    {6272,5120,896,768},
    {6400,5248,896,768},
    {6528,5376,896,768},
    {6656,5504,896,768},
    {6784,5632,896,768},
    {6912,768,1024,768},
    {7040,896,1024,768},
    {7168,1024,1024,768},
    {7296,1152,1024,768},
    {7424,1280,1024,768},
    {7552,1408,1024,768},
    {7680,1536,1024,768},
    {7808,1664,1024,768},
    {7936,1792,1024,768},
    {8064,2688,1024,768},
    {8192,2816,1024,768},
    {8320,2944,1024,768},
    {8448,3072,1024,768},
    {8576,3200,1024,768},
    {8704,3328,1024,768},
    {8832,3456,1024,768},
    {8960,3584,1024,768},
    {9088,3712,1024,768},
    {9216,4608,1024,768},
    {9344,4736,1024,768},
    {9472,4864,1024,768},
    {9600,4992,1024,768},
    {9728,5120,1024,768},
    {9856,5248,1024,768},
    {9984,5376,1024,768},
    {10112,5504,1024,768},
    {10240,5632,1024,768},
    {0,1920,1152,1920},
    {128,2048,1152,1920},
    {256,2176,1152,1920},
    {384,2304,1152,1920},
    {512,2432,1152,1920},
    {640,2560,1152,1920},
    {768,2688,1152,1920},
    {896,2816,1152,1920},
    {1024,2944,1152,1920},
    {1152,3840,1152,1920},
    {1280,3968,1152,1920},
    {1408,4096,1152,1920},
    {1536,4224,1152,1920},
    {1664,4352,1152,1920},
    {1792,4480,1152,1920},
    {1920,4608,1152,1920},
    {2048,4736,1152,1920},
    {2176,4864,1152,1920},
    {2304,5760,1152,1920},
    {2432,5888,1152,1920},
    {2560,6016,1152,1920},
    {2688,6144,1152,1920},
    {2816,6272,1152,1920},
    {2944,6400,1152,1920},
    {3072,6528,1152,1920},
    {3200,6656,1152,1920},
    {3328,6784,1152,1920},
    {3456,1920,1280,1920},
    {3584,2048,1280,1920},
    {3712,2176,1280,1920},
    {3840,2304,1280,1920},
    {3968,2432,1280,1920},
    {4096,2560,1280,1920},
    {4224,2688,1280,1920},
    {4352,2816,1280,1920},
    {4480,2944,1280,1920},
    {4608,3840,1280,1920},
    {4736,3968,1280,1920},
    {4864,4096,1280,1920},
    {4992,4224,1280,1920},
    {5120,4352,1280,1920},
    {5248,4480,1280,1920},
    {5376,4608,1280,1920},
    {5504,4736,1280,1920},
    {5632,4864,1280,1920},
    {5760,5760,1280,1920},
    {5888,5888,1280,1920},
    {6016,6016,1280,1920},
    {6144,6144,1280,1920},
    {6272,6272,1280,1920},
    {6400,6400,1280,1920},
    {6528,6528,1280,1920},
    {6656,6656,1280,1920},
    {6784,6784,1280,1920},
    {6912,1920,1408,1920},
    {7040,2048,1408,1920},
    {7168,2176,1408,1920},
    {7296,2304,1408,1920},
    {7424,2432,1408,1920},
    {7552,2560,1408,1920},
    {7680,2688,1408,1920},
    {7808,2816,1408,1920},
    {7936,2944,1408,1920},
    {8064,3840,1408,1920},
    {8192,3968,1408,1920},
    {8320,4096,1408,1920},
    {8448,4224,1408,1920},
    {8576,4352,1408,1920},
    {8704,4480,1408,1920},
    {8832,4608,1408,1920},
    {8960,4736,1408,1920},
    {9088,4864,1408,1920},
    {9216,5760,1408,1920},
    {9344,5888,1408,1920},
    {9472,6016,1408,1920},
    {9600,6144,1408,1920},
    {9728,6272,1408,1920},
    {9856,6400,1408,1920},
    {9984,6528,1408,1920},
    {10112,6656,1408,1920},
    {10240,6784,1408,1920},
    {0,2304,1536,2304},
    {128,2432,1536,2304},
    {256,2560,1536,2304},
    {384,2688,1536,2304},
    {512,2816,1536,2304},
    {640,2944,1536,2304},
    {768,3072,1536,2304},
    {896,3200,1536,2304},
    {1024,3328,1536,2304},
    {1152,4224,1536,2304},
    {1280,4352,1536,2304},
    {1408,4480,1536,2304},
    {1536,4608,1536,2304},
    {1664,4736,1536,2304},
    {1792,4864,1536,2304},
    {1920,4992,1536,2304},
    {2048,5120,1536,2304},
    {2176,5248,1536,2304},
    {2304,6144,1536,2304},
    {2432,6272,1536,2304},
    {2560,6400,1536,2304},
    {2688,6528,1536,2304},
    {2816,6656,1536,2304},
    {2944,6784,1536,2304},
    {3072,6912,1536,2304},
    {3200,7040,1536,2304},
    {3328,7168,1536,2304},
    {3456,2304,1664,2304},
    {3584,2432,1664,2304},
    {3712,2560,1664,2304},
    {3840,2688,1664,2304},
    {3968,2816,1664,2304},
    {4096,2944,1664,2304},
    {4224,3072,1664,2304},
    {4352,3200,1664,2304},
    {4480,3328,1664,2304},
    {4608,4224,1664,2304},
    {4736,4352,1664,2304},
    {4864,4480,1664,2304},
    {4992,4608,1664,2304},
    {5120,4736,1664,2304},
    {5248,4864,1664,2304},
    {5376,4992,1664,2304},
    {5504,5120,1664,2304},
    {5632,5248,1664,2304},
    {5760,6144,1664,2304},
    {5888,6272,1664,2304},
    {6016,6400,1664,2304},
    {6144,6528,1664,2304},
    {6272,6656,1664,2304},
    {6400,6784,1664,2304},
    {6528,6912,1664,2304},
    {6656,7040,1664,2304},
    {6784,7168,1664,2304},
    {6912,2304,1792,2304},
    {7040,2432,1792,2304},
    {7168,2560,1792,2304},
    {7296,2688,1792,2304},
    {7424,2816,1792,2304},
    {7552,2944,1792,2304},
    {7680,3072,1792,2304},
    {7808,3200,1792,2304},
    {7936,3328,1792,2304},
    {8064,4224,1792,2304},
    {8192,4352,1792,2304},
    {8320,4480,1792,2304},
    {8448,4608,1792,2304},
    {8576,4736,1792,2304},
    {8704,4864,1792,2304},
    {8832,4992,1792,2304},
    {8960,5120,1792,2304},
    {9088,5248,1792,2304},
    {9216,6144,1792,2304},
    {9344,6272,1792,2304},
    {9472,6400,1792,2304},
    {9600,6528,1792,2304},
    {9728,6656,1792,2304},
    {9856,6784,1792,2304},
    {9984,6912,1792,2304},
    {10112,7040,1792,2304},
    {10240,7168,1792,2304},
    {0,2688,1920,2688},
    {128,2816,1920,2688},
    {256,2944,1920,2688},
    {384,3072,1920,2688},
    {512,3200,1920,2688},
    {640,3328,1920,2688},
    {768,3456,1920,2688},
    {896,3584,1920,2688},
    {1024,3712,1920,2688},
    {1152,4608,1920,2688},
    {1280,4736,1920,2688},
    {1408,4864,1920,2688},
    {1536,4992,1920,2688},
    {1664,5120,1920,2688},
    {1792,5248,1920,2688},
    {1920,5376,1920,2688},
    {2048,5504,1920,2688},
    {2176,5632,1920,2688},
    {2304,6528,1920,2688},
    {2432,6656,1920,2688},
    {2560,6784,1920,2688},
    {2688,6912,1920,2688},
    {2816,7040,1920,2688},
    {2944,7168,1920,2688},
    {3072,7296,1920,2688},
    {3200,7424,1920,2688},
    {3328,7552,1920,2688},
    {3456,2688,2048,2688},
    {3584,2816,2048,2688},
    {3712,2944,2048,2688},
    {3840,3072,2048,2688},
    {3968,3200,2048,2688},
    {4096,3328,2048,2688},
    {4224,3456,2048,2688},
    {4352,3584,2048,2688},
    {4480,3712,2048,2688},
    {4608,4608,2048,2688},
    {4736,4736,2048,2688},
    {4864,4864,2048,2688},
    {4992,4992,2048,2688},
    {5120,5120,2048,2688},
    {5248,5248,2048,2688},
    {5376,5376,2048,2688},
    {5504,5504,2048,2688},
    {5632,5632,2048,2688},
    {5760,6528,2048,2688},
    {5888,6656,2048,2688},
    {6016,6784,2048,2688},
    {6144,6912,2048,2688},
    {6272,7040,2048,2688},
    {6400,7168,2048,2688},
    {6528,7296,2048,2688},
    {6656,7424,2048,2688},
    {6784,7552,2048,2688},
    {6912,2688,2176,2688},
    {7040,2816,2176,2688},
    {7168,2944,2176,2688},
    {7296,3072,2176,2688},
    {7424,3200,2176,2688},
    {7552,3328,2176,2688},
    {7680,3456,2176,2688},
    {7808,3584,2176,2688},
    {7936,3712,2176,2688},
    {8064,4608,2176,2688},
    {8192,4736,2176,2688},
    {8320,4864,2176,2688},
    {8448,4992,2176,2688},
    {8576,5120,2176,2688},
    {8704,5248,2176,2688},
    {8832,5376,2176,2688},
    {8960,5504,2176,2688},
    {9088,5632,2176,2688},
    {9216,6528,2176,2688},
    {9344,6656,2176,2688},
    {9472,6784,2176,2688},
    {9600,6912,2176,2688},
    {9728,7040,2176,2688},
    {9856,7168,2176,2688},
    {9984,7296,2176,2688},
    {10112,7424,2176,2688},
    {10240,7552,2176,2688},
    {0,3840,2304,3840},
    {128,3968,2304,3840},
    {256,4096,2304,3840},
    {384,4224,2304,3840},
    {512,4352,2304,3840},
    {640,4480,2304,3840},
    {768,4608,2304,3840},
    {896,4736,2304,3840},
    {1024,4864,2304,3840},
    {1152,5760,2304,3840},
    {1280,5888,2304,3840},
    {1408,6016,2304,3840},
    {1536,6144,2304,3840},
    {1664,6272,2304,3840},
    {1792,6400,2304,3840},
    {1920,6528,2304,3840},
    {2048,6656,2304,3840},
    {2176,6784,2304,3840},
    {2304,7680,2304,3840},
    {2432,7808,2304,3840},
    {2560,7936,2304,3840},
    {2688,8064,2304,3840},
    {2816,8192,2304,3840},
    {2944,8320,2304,3840},
    {3072,8448,2304,3840},
    {3200,8576,2304,3840},
    {3328,8704,2304,3840},
    {3456,3840,2432,3840},
    {3584,3968,2432,3840},
    {3712,4096,2432,3840},
    {3840,4224,2432,3840},
    {3968,4352,2432,3840},
    {4096,4480,2432,3840},
    {4224,4608,2432,3840},
    {4352,4736,2432,3840},
    {4480,4864,2432,3840},
    {4608,5760,2432,3840},
    {4736,5888,2432,3840},
    {4864,6016,2432,3840},
    {4992,6144,2432,3840},
    {5120,6272,2432,3840},
    {5248,6400,2432,3840},
    {5376,6528,2432,3840},
    {5504,6656,2432,3840},
    {5632,6784,2432,3840},
    {5760,7680,2432,3840},
    {5888,7808,2432,3840},
    {6016,7936,2432,3840},
    {6144,8064,2432,3840},
    {6272,8192,2432,3840},
    {6400,8320,2432,3840},
    {6528,8448,2432,3840},
    {6656,8576,2432,3840},
    {6784,8704,2432,3840},
    {6912,3840,2560,3840},
    {7040,3968,2560,3840},
    {7168,4096,2560,3840},
    {7296,4224,2560,3840},
    {7424,4352,2560,3840},
    {7552,4480,2560,3840},
    {7680,4608,2560,3840},
    {7808,4736,2560,3840},
    {7936,4864,2560,3840},
    {8064,5760,2560,3840},
    {8192,5888,2560,3840},
    {8320,6016,2560,3840},
    {8448,6144,2560,3840},
    {8576,6272,2560,3840},
    {8704,6400,2560,3840},
    {8832,6528,2560,3840},
    {8960,6656,2560,3840},
    {9088,6784,2560,3840},
    {9216,7680,2560,3840},
    {9344,7808,2560,3840},
    {9472,7936,2560,3840},
    {9600,8064,2560,3840},
    {9728,8192,2560,3840},
    {9856,8320,2560,3840},
    {9984,8448,2560,3840},
    {10112,8576,2560,3840},
    {10240,8704,2560,3840},
    {0,4224,2688,4224},
    {128,4352,2688,4224},
    {256,4480,2688,4224},
    {384,4608,2688,4224},
    {512,4736,2688,4224},
    {640,4864,2688,4224},
    {768,4992,2688,4224},
    {896,5120,2688,4224},
    {1024,5248,2688,4224},
    {1152,6144,2688,4224},
    {1280,6272,2688,4224},
    {1408,6400,2688,4224},
    {1536,6528,2688,4224},
    {1664,6656,2688,4224},
    {1792,6784,2688,4224},
    {1920,6912,2688,4224},
    {2048,7040,2688,4224},
    {2176,7168,2688,4224},
    {2304,8064,2688,4224},
    {2432,8192,2688,4224},
    {2560,8320,2688,4224},
    {2688,8448,2688,4224},
    {2816,8576,2688,4224},
    {2944,8704,2688,4224},
    {3072,8832,2688,4224},
    {3200,8960,2688,4224},
    {3328,9088,2688,4224},
    {3456,4224,2816,4224},
    {3584,4352,2816,4224},
    {3712,4480,2816,4224},
    {3840,4608,2816,4224},
    {3968,4736,2816,4224},
    {4096,4864,2816,4224},
    {4224,4992,2816,4224},
    {4352,5120,2816,4224},
    {4480,5248,2816,4224},
    {4608,6144,2816,4224},
    {4736,6272,2816,4224},
    {4864,6400,2816,4224},
    {4992,6528,2816,4224},
    {5120,6656,2816,4224},
    {5248,6784,2816,4224},
    {5376,6912,2816,4224},
    {5504,7040,2816,4224},
    {5632,7168,2816,4224},
    {5760,8064,2816,4224},
    {5888,8192,2816,4224},
    {6016,8320,2816,4224},
    {6144,8448,2816,4224},
    {6272,8576,2816,4224},
    {6400,8704,2816,4224},
    {6528,8832,2816,4224},
    {6656,8960,2816,4224},
    {6784,9088,2816,4224},
    {6912,4224,2944,4224},
    {7040,4352,2944,4224},
    {7168,4480,2944,4224},
    {7296,4608,2944,4224},
    {7424,4736,2944,4224},
    {7552,4864,2944,4224},
    {7680,4992,2944,4224},
    {7808,5120,2944,4224},
    {7936,5248,2944,4224},
    {8064,6144,2944,4224},
    {8192,6272,2944,4224},
    {8320,6400,2944,4224},
    {8448,6528,2944,4224},
    {8576,6656,2944,4224},
    {8704,6784,2944,4224},
    {8832,6912,2944,4224},
    {8960,7040,2944,4224},
    {9088,7168,2944,4224},
    {9216,8064,2944,4224},
    {9344,8192,2944,4224},
    {9472,8320,2944,4224},
    {9600,8448,2944,4224},
    {9728,8576,2944,4224},
    {9856,8704,2944,4224},
    {9984,8832,2944,4224},
    {10112,8960,2944,4224},
    {10240,9088,2944,4224},
    {0,4608,3072,4608},
    {128,4736,3072,4608},
    {256,4864,3072,4608},
    {384,4992,3072,4608},
    {512,5120,3072,4608},
    {640,5248,3072,4608},
    {768,5376,3072,4608},
    {896,5504,3072,4608},
    {1024,5632,3072,4608},
    {1152,6528,3072,4608},
    {1280,6656,3072,4608},
    {1408,6784,3072,4608},
    {1536,6912,3072,4608},
    {1664,7040,3072,4608},
    {1792,7168,3072,4608},
    {1920,7296,3072,4608},
    {2048,7424,3072,4608},
    {2176,7552,3072,4608},
    {2304,8448,3072,4608},
    {2432,8576,3072,4608},
    {2560,8704,3072,4608},
    {2688,8832,3072,4608},
    {2816,8960,3072,4608},
    {2944,9088,3072,4608},
    {3072,9216,3072,4608},
    {3200,9344,3072,4608},
    {3328,9472,3072,4608},
    {3456,4608,3200,4608},
    {3584,4736,3200,4608},
    {3712,4864,3200,4608},
    {3840,4992,3200,4608},
    {3968,5120,3200,4608},
    {4096,5248,3200,4608},
    {4224,5376,3200,4608},
    {4352,5504,3200,4608},
    {4480,5632,3200,4608},
    {4608,6528,3200,4608},
    {4736,6656,3200,4608},
    {4864,6784,3200,4608},
    {4992,6912,3200,4608},
    {5120,7040,3200,4608},
    {5248,7168,3200,4608},
    {5376,7296,3200,4608},
    {5504,7424,3200,4608},
    {5632,7552,3200,4608},
    {5760,8448,3200,4608},
    {5888,8576,3200,4608},
    {6016,8704,3200,4608},
    {6144,8832,3200,4608},
    {6272,8960,3200,4608},
    {6400,9088,3200,4608},
    {6528,9216,3200,4608},
    {6656,9344,3200,4608},
    {6784,9472,3200,4608},
    {6912,4608,3328,4608},
    {7040,4736,3328,4608},
    {7168,4864,3328,4608},
    {7296,4992,3328,4608},
    {7424,5120,3328,4608},
    {7552,5248,3328,4608},
    {7680,5376,3328,4608},
    {7808,5504,3328,4608},
    {7936,5632,3328,4608},
    {8064,6528,3328,4608},
    {8192,6656,3328,4608},
    {8320,6784,3328,4608},
    {8448,6912,3328,4608},
    {8576,7040,3328,4608},
    {8704,7168,3328,4608},
    {8832,7296,3328,4608},
    {8960,7424,3328,4608},
    {9088,7552,3328,4608},
    {9216,8448,3328,4608},
    {9344,8576,3328,4608},
    {9472,8704,3328,4608},
    {9600,8832,3328,4608},
    {9728,8960,3328,4608},
    {9856,9088,3328,4608},
    {9984,9216,3328,4608},
    {10112,9344,3328,4608},
    {10240,9472,3328,4608},
    {10240,9472,3328,4608}
  };

  int i=1;
  // test process
  initial begin
    ctrl_i = '0;
    registers_read_i = '0;
    registers_read_i[0]  = nif_div_TP * 128;                  // nif
    registers_read_i[1]  = nof_div_TP * 128;                  // nof
    registers_read_i[2]  = nof_div_TP * 128 * ow;             // ow_X_nof
    registers_read_i[3]  = nif_div_TP * 128 * (ow + fs0 - 1); // w_X_nif
    registers_read_i[4]  = 128;                               // TPin
    registers_read_i[5]  = nif_div_TP * 128 * fs1*fs0;        // nif_X_fs2
    registers_read_i[6]  = 128;                               // TPout
    registers_read_i[7]  = 128 + nif_div_TP*128 * (ow-1);     // x_iter
    registers_read_i[8]  = nif_div_TP*128 * fs0;              // x_maj_iter
    registers_read_i[10] = 0;                                 // zero
    registers_read_i[11] = 128*128;                           // TP2
    uloop_code_i       = '0;
    uloop_code_i.code  = 192'h00238d9128070238c91280702389502215c0885102214408; // see uloop-example/uloop_compile.py
    uloop_code_i.loops = 48'h6c4c33221202;                                      // see uloop-example/uloop_compile.py
    uloop_code_i.range[5] = oh;
    uloop_code_i.range[4] = ow;
    uloop_code_i.range[3] = nof_div_TP;
    uloop_code_i.range[2] = fs1;
    uloop_code_i.range[1] = fs0;
    uloop_code_i.range[0] = nif_div_TP;
    #(100*TCP);
    while(~flags_o.done) begin
      while(~flags_o.ready) begin // wait until the uloop is ready (if SHADOWED=1)
        if(flags_o.done)
          $finish();
        ctrl_i.enable = 1'b0;
        #(TCP);
      end
      while(~flags_o.valid) begin // get indeces from the uloop if it is ready
        if(flags_o.done)
          $finish();
        ctrl_i.enable = ~flags_o.done;
        #(TCP);
      end
      if ((flags_o.offs[0] != ground_truth[i][0]) ||
          (flags_o.offs[1] != ground_truth[i][1]) ||
          (flags_o.offs[2] != ground_truth[i][2]) ||
          (flags_o.offs[3] != ground_truth[i][3]))
        $fatal();
      i += 1;
      ctrl_i.enable = 1'b0;
      #(TCP);
    end
    #(20*TCP);
    $finish();
  end

endmodule // tb_hwpe_ctrl_uloop
